import 'dart:io';

import 'package:auto_route/auto_route.dart';
import 'package:casdon/build_gen/assets.gen.dart';
import 'package:casdon/core/logger/log.dart';
import 'package:casdon/core/utils/page_visibility_mixin.dart';
import 'package:casdon/modules/device/application/notification/scanner_service_notifier.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:image_picker/image_picker.dart';
import 'package:mobile_scanner/mobile_scanner.dart';

import 'package:permission_handler/permission_handler.dart';

@RoutePage()
class QRScannerScreen extends ConsumerStatefulWidget {
  const QRScannerScreen({super.key});

  @override
  ConsumerState<QRScannerScreen> createState() => _QRScannerScreenState();
}

class _QRScannerScreenState extends ConsumerState<QRScannerScreen>
    with
        SingleTickerProviderStateMixin,
        PageVisibilityMixin,
        WidgetsBindingObserver {
  ProviderSubscription<bool>? _tmBindSub;
  // 防抖记录：记录已处理的二维码和时间戳
  final Map<String, DateTime> _processedQRCodes = {};
  static const Duration _debounceDuration = Duration(seconds: 10);
  MobileScannerController? _scannerController;
  bool _isScanning = true;
  bool _hasCameraPermission = false;
  bool _permissionChecked = false;
  late final AnimationController _scanLineController;
  late final Animation<double> _scanLineAnimation;

  @override
  void initState() {
    super.initState();
    _scanLineController = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
    )..repeat(reverse: true);
    _scanLineAnimation = CurvedAnimation(
      parent: _scanLineController,
      curve: Curves.easeInOut,
    );
    _ensureCameraPermission();

    _tmBindSub = ref.listenManual<bool>(tmBindSuccessProvider, (
      previous,
      next,
    ) async {
      if (next == true && previous == false) {
        final handler = ref.read(scanResultHandlerProvider);
        await handler.onTMBindSuccess(ref.context);
        ref.read(tmBindSuccessProvider.notifier).state = false;
      }
    }, fireImmediately: false);
  }

  @override
  Widget build(BuildContext context) {
    return buildPageVisibilityDetector(
      context,
      Scaffold(
        extendBodyBehindAppBar: true,
        appBar: AppBar(
          title: const Text('添加设备'),
          centerTitle: true,
          elevation: 0,
          foregroundColor: Colors.white,
          iconTheme: const IconThemeData(color: Colors.white),
          backgroundColor: Colors.transparent,
        ),
        backgroundColor: Colors.grey.shade400,
        body: Column(
          children: [
            Expanded(child: _buildScannerView(context, ref)),
            if (!(_permissionChecked && _hasCameraPermission))
              _buildBottomActionBar(ref)
            else
              const SizedBox.shrink(),
          ],
        ),
      ),
    );
  }

  Widget _buildScannerView(BuildContext context, WidgetRef ref) {
    if (!_permissionChecked) {
      return const Center(child: CircularProgressIndicator());
    }
    if (!_hasCameraPermission) {
      return _buildPermissionDenied(context);
    }
    final controller = ref.watch(scannerControllerProvider);
    _scannerController = controller;
    final handler = ref.watch(scanResultHandlerProvider);

    return Stack(
      children: [
        Positioned.fill(
          child: MobileScanner(
            controller: controller,
            onDetect: (capture) async {
              final barcode = capture.barcodes.first;
              if (barcode.rawValue == null) {
                return;
              }

              final qrCode = barcode.rawValue!;
              Log.d('112112二维码扫码结果: $qrCode');

              // 防抖检查：如果10秒内已经处理过相同的二维码，直接返回
              if (_processedQRCodes.containsKey(qrCode)) {
                final lastProcessedTime = _processedQRCodes[qrCode]!;
                final now = DateTime.now();
                final timeSinceLastProcess = now.difference(lastProcessedTime);

                if (timeSinceLastProcess < _debounceDuration) {
                  final remainingSeconds =
                      (_debounceDuration.inSeconds -
                      timeSinceLastProcess.inSeconds);
                  _processedQRCodes[qrCode] = DateTime.now();
                  Log.d('112112二维码已在 ${remainingSeconds}秒前处理过，跳过重复处理: $qrCode');
                  return;
                } else {
                  // 超过10秒，清除记录
                  _processedQRCodes.remove(qrCode);
                }
              }
              Log.d('112112二维码处理  $qrCode');
              _processedQRCodes[qrCode] = DateTime.now();
              ref.read(scanResultProvider.notifier).state = qrCode;
              final ret = await handler.handleBarcode(context, barcode);
              Log.d('112112二维码处理jieguo: $ret');

              if (!mounted) {
                return;
              }

              // 如果处理成功，记录二维码和时间戳
              if (ret) {
                Log.d('112112二维码处理成功，已记录防抖: $qrCode');
              }

              if (!ret) {
                ScaffoldMessenger.of(
                  context,
                ).showSnackBar(const SnackBar(content: Text('不支持该协议')));
              }
            },
          ),
        ),
        Positioned.fill(child: Container(color: Colors.black.withOpacity(0.2))),
        Positioned.fill(
          child: LayoutBuilder(
            builder: (context, constraints) {
              final lineHeight = 40.h;
              final travelRange = 360.h; // 屏幕中心上下各180
              final centerY = constraints.maxHeight / 2;
              final startTop = centerY - travelRange / 2 - 50.h;

              return AnimatedBuilder(
                animation: _scanLineAnimation,
                builder: (context, child) {
                  final currentTop =
                      startTop + _scanLineAnimation.value * travelRange;
                  return Stack(
                    children: [
                      Positioned(
                        top: currentTop,
                        left: 0,
                        right: 0,
                        child: child!,
                      ),
                      Positioned(
                        left: 0,
                        right: 0,
                        bottom: 48.h,
                        child: _buildBottomActionBar(ref),
                      ),
                    ],
                  );
                },

                child: Image.asset(
                  Assets.images.icScannerLine.path,
                  width: constraints.maxWidth,
                  height: lineHeight,
                  fit: BoxFit.fill,
                ),
              );
            },
          ),
        ),
      ],
    );
  }

  Widget _buildPermissionDenied(BuildContext context) {
    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          const Icon(Icons.camera_alt_outlined, size: 48, color: Colors.grey),
          SizedBox(height: 12.h),
          const Text('相机权限已关闭，无法扫码'),
          SizedBox(height: 12.h),
          ElevatedButton(onPressed: _openSettings, child: const Text('前往设置开启')),
        ],
      ),
    );
  }

  Widget _buildBottomActionBar(WidgetRef ref) {
    if (_permissionChecked && _hasCameraPermission) {
      return _buildModernBottomActionBar(ref);
    }
    return _buildLegacyBottomActionBar(ref);
  }

  Widget _buildLegacyBottomActionBar(WidgetRef ref) {
    return Padding(
      padding: EdgeInsets.all(16.w),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          ElevatedButton.icon(
            icon: Icon(Icons.photo_library, size: 44.w),
            label: const Text('相册'),
            onPressed: () => _pickImageFromGallery(ref),
          ),
          ElevatedButton.icon(
            icon: Icon(Icons.photo_library, size: 44.w),
            label: const Text('闪光灯'),
            onPressed: () => ref.read(scannerControllerProvider).toggleTorch(),
          ),
        ],
      ),
    );
  }

  Widget _buildModernBottomActionBar(WidgetRef ref) {
    final controller = ref.watch(scannerControllerProvider);
    return ValueListenableBuilder<MobileScannerState>(
      valueListenable: controller,
      builder: (context, state, _) {
        final torchState = state.torchState;
        return Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            _buildCircleAction(
              iconPath: Assets.images.icPhotoPic.path,
              label: '相册',
              onTap: () => _pickImageFromGallery(ref),
            ),
            _buildCircleAction(
              iconPath: torchState == TorchState.on
                  ? Assets.images.icLightOn.path
                  : Assets.images.icLightOff.path,
              label: torchState == TorchState.on ? '关闭灯光' : '打开灯光',
              onTap: () => controller.toggleTorch(),
            ),
          ],
        );
      },
    );
  }

  Widget _buildCircleAction({
    required String iconPath,
    required String label,
    required VoidCallback onTap,
  }) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        InkWell(
          onTap: onTap,
          borderRadius: BorderRadius.circular(24),
          child: Ink(
            width: 48.w,
            height: 48.w,
            decoration: BoxDecoration(
              color: Colors.grey.withOpacity(0.6),
              shape: BoxShape.circle,
            ),
            child: Center(
              child: Image.asset(
                iconPath,
                width: 44.w,
                height: 44.w,
                fit: BoxFit.contain,
              ),
            ),
          ),
        ),
        const SizedBox(height: 8),
        Text(label, style: const TextStyle(color: Colors.white, fontSize: 12)),
      ],
    );
  }

  Future<void> _pickImageFromGallery(WidgetRef ref) async {
    try {
      final picker = ref.read(imagePickerProvider);
      final image = await picker.pickImage(source: ImageSource.gallery);

      if (image != null) {
        // 直接用 scanner controller 解析本地图像
        final controller = ref.read(scannerControllerProvider);
        final capture = await controller.analyzeImage(image.path);
        if (capture != null && capture.barcodes.isNotEmpty) {
          final barcode = capture.barcodes.first;
          ref.read(scanResultProvider.notifier).state = barcode.rawValue ?? '';
          final handler = ref.read(scanResultHandlerProvider);
          final success = await handler.handleBarcode(ref.context, barcode);
          if (!success && ref.context.mounted) {
            ScaffoldMessenger.of(
              ref.context,
            ).showSnackBar(const SnackBar(content: Text('未识别到二维码')));
          }
        } else if (ref.context.mounted) {
          ScaffoldMessenger.of(
            ref.context,
          ).showSnackBar(const SnackBar(content: Text('未识别到二维码')));
        }
      }
    } catch (e) {
      if (ref.context.mounted == false) {
        return;
      }
      ScaffoldMessenger.of(
        ref.context,
      ).showSnackBar(SnackBar(content: Text('读取图片失败: $e')));
    }
  }

  Future<void> _pauseScanner() async {
    if (!_isScanning) {
      return;
    }
    try {
      await _scannerController?.stop();
      _isScanning = false;
    } catch (e, st) {
      Log.e('暂停扫码失败: $e', e, st);
    }
  }

  Future<void> _resumeScanner() async {
    if (_isScanning) {
      return;
    }
    try {
      await _scannerController?.start();
      _isScanning = true;
    } catch (e, st) {
      Log.e('恢复扫码失败: $e', e, st);
    }
  }

  @override
  void onPageHidden() {
    _pauseScanner();
  }

  @override
  void onPageVisible() {
    // 重置防抖记录，确保返回页面后可立即重新处理扫码
    _processedQRCodes.clear();
    _resumeScanner();
  }

  @override
  void onAppPaused() {
    _pauseScanner();
  }

  @override
  void onAppResumed() {
    _resumeScanner();
  }

  @override
  void dispose() {
    _pauseScanner();
    _tmBindSub?.close();
    _scanLineController.dispose();
    super.dispose();
  }

  Future<void> _ensureCameraPermission() async {
    try {
      var status = await Permission.camera.status;
      if (!status.isGranted) {
        status = await Permission.camera.request();
      }
      if (mounted) {
        setState(() {
          _permissionChecked = true;
          _hasCameraPermission = status.isGranted;
        });
      }
    } catch (e, st) {
      Log.e('检查相机权限失败', e, st);
      if (mounted) {
        setState(() {
          _permissionChecked = true;
          _hasCameraPermission = false;
        });
      }
    }
  }

  Future<void> _openSettings() async {
    try {
      await openAppSettings();
    } catch (e) {
      Log.e('打开设置失败', e, StackTrace.current);
    }
    _ensureCameraPermission();
  }
}
